/*
-------------------------------------------------

	PNG.cpp

	Dmitriy Kuzmenko (Dgut)

-------------------------------------------------
*/

#include "PNG.h"
#include "File.h"

namespace Autumn
{

PNG::PNG( const char * fileName ) :
	width	( 0 ),
	height	( 0 ),
	type	( 0 ),
	data	( 0 )
{
	FILE * stream = gFile.Open( fileName, "rb" );
	if( !stream )
		return;

	png_byte header[ 8 ];

	fread( header, 1, sizeof( header ), stream );
	if( png_sig_cmp( header, 0, 8 ) )
	{
		fclose( stream );
		return;
	}

	png_struct * png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
	if( !png )
	{
		fclose( stream );
		return;
	}

	png_info * info = png_create_info_struct( png );
	if( !info || setjmp( png_jmpbuf( png ) ) )
	{
		png_destroy_read_struct( &png, 0, 0 );
		fclose( stream );
		return;
	}

	png_init_io( png, stream );
	png_set_sig_bytes( png, sizeof( header ) );
	png_read_info( png, info );

	
	if( png_get_color_type( png, info ) == PNG_COLOR_TYPE_GRAY || png_get_color_type( png, info ) == PNG_COLOR_TYPE_GRAY_ALPHA )
		png_set_gray_to_rgb( png );
	if( png_get_color_type( png, info ) == PNG_COLOR_TYPE_PALETTE )
		png_set_palette_to_rgb( png );
	png_read_update_info( png, info );

	type = png_get_color_type( png, info );

	width = png_get_image_width( png, info );
	height = png_get_image_height( png, info );

//	png_destroy_read_struct(

	data = new png_byte[ png_get_rowbytes( png, info ) * height ];

	png_byte * * rows = new png_byte *[ height ];
	for( int i = 0; i < height; i++ )
		rows[ i ] = data + i * png_get_rowbytes( png, info );

	png_read_image( png, rows );

	delete[] rows;

	fclose( stream );

	for( int i = 0; i < height / 2; i++ )
		for( int j = 0; j < png_get_rowbytes( png, info ); j++ )
		{
			const png_byte temp = data[ i * png_get_rowbytes( png, info ) + j ];
			data[ i * png_get_rowbytes( png, info ) + j ] = data[ ( height - i - 1 ) * png_get_rowbytes( png, info ) + j ];
			data[ ( height - i - 1 ) * png_get_rowbytes( png, info ) + j ] = temp;
		}

	/*if( type & PNG_COLOR_MASK_ALPHA )
		for( int i = 0; i < width * height * 4; i += 4 )
		{
			if( data[ i + 3 ] )
				continue;

			data[ i + 0 ] = 0;
			data[ i + 1 ] = 0;
			data[ i + 2 ] = 0;
		}*/

	png_destroy_info_struct( png, &info );
	png_destroy_read_struct( &png, 0, 0 );
}

PNG::~PNG( void )
{
	delete[] data;
}

const png_uint_32 PNG::GetWidth( void ) const
{
	return width;
}

const png_uint_32 PNG::GetHeight( void ) const
{
	return height;
}

const png_byte PNG::GetType( void ) const
{
	return type;
}

png_byte * const PNG::GetData( void ) const
{
	return data;
}

}	// namespace Autumn